package com.example.demo.utils;


import com.example.demo.domain.AjaxResult;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.model.GeneratePresignedUrlRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.utils.StringUtils;
import lombok.Data;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * 知识图谱后端文件处理工具类
 * 上传文件工具
 * @author wzh
 * @date 2025.4.16
 */

@Component
@Data
public class CosFileUpload {

    @Autowired
    private COSClient cosClient;

    @Autowired
    private CosConfigProperties cosConfig;

    /**
     * 上传文件到 COS，返回临时访问链接（预签名 URL）
     * @param files 上传的文件数组
     * @return 临时访问链接（逗号分隔）
     */
    public AjaxResult upload(MultipartFile[] files) {
        List<Map<String, String>> fileList = new ArrayList<>();

        try {
            for (MultipartFile file : files) {
                String originalFileName = file.getOriginalFilename();
                if (StringUtils.isNullOrEmpty(originalFileName)) {
                    throw new IllegalArgumentException("文件名不能为空");
                }

                // 生成唯一文件路径（避免重复）
                String filePath = getUniqueFilePath(originalFileName, cosConfig.getFolder());

                // 上传文件到 COS
                try (InputStream inputStream = file.getInputStream()) {  // 自动关闭流
                    ObjectMetadata metadata = new ObjectMetadata();
                    metadata.setContentLength(file.getSize());
                    metadata.setContentType(file.getContentType());

                    cosClient.putObject(
                            new PutObjectRequest(cosConfig.getBucketName(), filePath, inputStream, metadata)
                    );
                }

                // 生成预签名 URL（临时访问链接，有效期 1 小时）
                GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(
                        cosConfig.getBucketName(),
                        filePath,
                        HttpMethodName.GET
                );
                req.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000));  // 1小时后过期

                URL presignedUrl = cosClient.generatePresignedUrl(req);
//              tempUrls.add(presignedUrl.toString());
                // 构建文件信息 Map
                Map<String, String> fileInfo = new LinkedHashMap<>();
                fileInfo.put("fileName", filePath);
                fileInfo.put("url", presignedUrl.toString());
                fileList.add(fileInfo);
            }
            return AjaxResult.success(fileList);  // 返回文件在cos的文件名和一小时内可供访问的临时链接

        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error("文件上传失败: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("系统错误: " + e.getMessage());
        }
    }

    /**
     * 上传单个文件并且返回文件名
     * @param file
     * @return
     */
    public AjaxResult uploadSingle(MultipartFile file) {
        try {

            String originalFileName = file.getOriginalFilename();
            if (StringUtils.isNullOrEmpty(originalFileName)) {
                throw new IllegalArgumentException("文件名不能为空");
            }

            // 生成唯一文件路径（避免重复）
            String filePath = getUniqueFilePath(originalFileName, cosConfig.getFolder());

            // 上传文件到 COS
            try (InputStream inputStream = file.getInputStream()) {  // 自动关闭流
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentLength(file.getSize());
                metadata.setContentType(file.getContentType());

                cosClient.putObject(
                        new PutObjectRequest(cosConfig.getBucketName(), filePath, inputStream, metadata)
                );
            }

            return AjaxResult.success(filePath);  // 返回文件在cos的文件名和一小时内可供访问的临时链接

        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error("文件上传失败: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("系统错误: " + e.getMessage());
        }
    }

    /**
     * 生成唯一文件路径（包含 UUID 防止重复）
     * @param originalFileName 原始文件名
     * @param folder 存储目录
     * @return 唯一文件路径（如 resource/20231030120000_abc123_我的文件.pdf）
     */
    private String getUniqueFilePath(String originalFileName, String folder) {
        // 提取文件后缀
//        String fileExt = "";
//        int dotIndex = originalFileName.lastIndexOf(".");
//        if (dotIndex > 0) {
//            fileExt = originalFileName.substring(dotIndex);
//        }
//
//        // 清理文件名（去除非字母数字汉字字符）
//        String baseName = (dotIndex > 0) ? originalFileName.substring(0, dotIndex) : originalFileName;
//        String cleanName = baseName.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "_");

        // 组合唯一路径
        return new DateTime().toString("yyyyMMddHHmmss") + "_"
                + UUID.randomUUID().toString().substring(0, 8) + "_"  // 添加随机 UUID 片段
                + originalFileName;
//                + fileExt;
    }
}
